//
//  MessageListVC+Options.swift
//  ZIMKit
//
//  Created by Kael Ding on 2022/9/26.
//

import Foundation
import ZIM

extension ZIMKitMessagesListVC: MessageOptionsViewDelegate {
    func showOptionsView(_ cell: MessageCell, _ messageVM: MessageViewModel) {
        if messageVM.message.type == .unknown {
            return
        }
        let window = UIApplication.key
        optionsView = MessageOptionsView(frame: view.bounds).withoutAutoresizingMaskConstraints
        optionsView!.delegate = self
        
        window?.embed(optionsView!)
        optionsView!.show(with: cell.containerView, messageVM: messageVM)
    }
    
    func hideOptionsView() {
        optionsView?.hide()
        optionsView = nil
    }
    
    func messageOptionsView(_ optionsView: MessageOptionsView, didSelectItemWith type: MessageOptionsView.ContentType) {
        switch type {
        case .copy:
            // 复制
            if optionsView.messageVM is TextMessageViewModel || (optionsView.messageVM is ReplyMessageViewModel && optionsView.messageVM.message.type == .text) {
                UIPasteboard.general.string = optionsView.messageVM.message.textContent.content
                HUDHelper.showMessage(L10n("message_copy_success"))
            }
            
        case .speaker:
            // 听筒、扬声器播放
            let isSpeakerOff = UserDefaults.standard.bool(forKey: "is_message_speaker_off")
            UserDefaults.standard.set(!isSpeakerOff, forKey: "is_message_speaker_off")
            let icon = isSpeakerOff ? "message_option_speaker" : "message_option_receiver"
            let tip = isSpeakerOff ? L10n("message_speaker_on_tip") : L10n("message_speaker_off_tip")
            HUDHelper.showImage(icon, message: tip)
        case .delete:
            // 删除
            deleteMessages([optionsView.messageVM])
        case .multipleChoice:
            // 多选
            enableMultiSelect(true, with: optionsView.messageVM)
        case .reply:
            //回复
            replyMessage(optionsView: optionsView)
        case .forward:
            //转发
            forwardMessage(messages: [optionsView.messageVM])
        case .revoke:
            // 撤回
            revokeMessage(view: optionsView)
            
        case .translation:
            xLog("音频文件路径：\(optionsView.messageVM.message.fileLocalPath)")
            let sendUserId = optionsView.messageVM.message.info.senderUserID
            xLog("发送方的 userid \(sendUserId)")
            // 是我自己发的，转文字，不翻译
            var from = UserProfile.country == 0 ? "zh": "ru"
            
            if (optionsView.messageVM.message.zim?.direction == ZIMMessageDirection.receive) {
                // 对方发的
                if let userModel = userModel {
                    from = userModel.country == 0 ? "zh": "ru"
                }
            }
            
            // 音频格式转换：m4a -> pcm
            var fileLocalPath = optionsView.messageVM.message.fileLocalPath
            
            do {
                fileLocalPath = try AudioConvertSwift.convertAACToPCM(aacPath: fileLocalPath)
                xLog("音频转换成功: \(fileLocalPath)")
            } catch {
                xLog("音频转换失败: \(error.localizedDescription)")
                
                // 检查原始文件是否存在
                if !FileManager.default.fileExists(atPath: fileLocalPath) {
                    xLog("原始音频文件不存在: \(fileLocalPath)")
                    YLHUD.showMessage("音频文件不存在，无法进行翻译")
                    return
                }
                
                // 尝试使用原始文件进行识别
                xLog("尝试使用原始音频文件进行识别")
                fileLocalPath = optionsView.messageVM.message.fileLocalPath
            }
            
            // 设置讯飞识别器
            IFlySpeechRecognizerManager.shared.delegate = self
            if (from == "zh") {
                IFlySpeechRecognizerManager.shared.setLanguage(IFlySpeechLanguage.chinese)
            } else {
                IFlySpeechRecognizerManager.shared.setLanguage(IFlySpeechLanguage.russian)
            }
            
            // 开始音频文件识别
            IFlySpeechRecognizerManager.shared.setAudioPath(path: fileLocalPath)
            
//            let audioConvert = AudioConvertSwift()
//            //1.转换wav
//            audioConvert.transcodeToWav(inputURL: URL(fileURLWithPath: fileLocalPath)) { result in
//                switch result {
//                case .success(let url):
//                    //2.上传aliyun
//                    self.uploadFile(fileURL: url) { audioURLString in
//                        if (audioURLString.isEmpty == false) {
//                            // 3.调用文件翻译
//                            YLRequest.request(OtherAPI.fileTrans(fileURL: audioURLString, language: from)) { result in
//                                switch result {
//                                case .success(let res):
//                                    guard let taskId = res.dataSources?["header"]["task_id"].stringValue else {
//                                        xLog("taskId 为空")
//                                        YLHUD.hideHUD()
//                                        return
//                                    }
//                                    self.transResultQuery(taskId: taskId, from: from, to: to, optionsView: optionsView)
//                                    
//                                case .failure(let err):
//                                    YLHUD.showHint(.error, err.errMsg)
//                                }
//                                
//                            }
//                        } else {
//                            YLHUD.showHint(.error, "上传失败")
//                        }
//                    }
//                    break;
//                case .failure(let error):
//                    xLog("失败了:\(error)");
//                    YLHUD.hideHUD()
//                    break;
//                }
//            }
            
            
//            YLHUD.showLottie()
//            SparkChainConfig.uploadFile(fileUrl: optionsView.messageVM.message.fileLocalPath, language: from) { isSuccess, result in
//                if isSuccess {
//                    xLog("转写 成功：\(result)")
//                    NeoNuiTranslation.translation(from: from, to: to, text: result) { sourceText, res in
//                        DispatchQueue.main.async { [weak self] in
//                            YLHUD.hideHUD()
//                            if let dst = res {
//                                YLHUD.hideHUD()
//                                xLog("翻译结果：\(dst)")
//                                optionsView.messageVM.isShowTranslation = true
//                                optionsView.messageVM.translationResult = "\(result)\n(\(dst))"
//                                optionsView.messageVM.setCellHeight()
//                                self?.tableView.reloadData()
//                                
//                            } else {
//                                YLHUD.showMessage("翻译失败")
//                            }
//                        }
//                    }
//                    
//                } else {
//                    YLHUD.showMessage("翻译失败")
//                    xLog("转写 失败：\(result)")
//                }
//            }
            
        case .reaction:
            print("---")
            
        }
    }
    
    func startTranslation(from: String, to: String, text: String) {
        // 如果需要翻译，可以在这里添加翻译逻辑
         NeoNuiTranslation.translation(from: from, to: to, text: text) { sourceText, res in
             DispatchQueue.main.async { [weak self] in
                 guard let self = self else { return }
                 YLHUD.hideHUD()
                 if let dst = res {
                     xLog("翻译结果：\(dst)")
                     optionsView?.messageVM.isShowTranslation = true
                     optionsView?.messageVM.translationResult = "\(text)\n(\(dst))"
                     optionsView?.messageVM.setCellHeight()
                     self.tableView.reloadData()
                    //  self.scrollToBottom(true)
                 // 这里不滚动到底部，而是滚动到当前消息下方，确保翻译条可见
                     if let index = self.viewModel.messageViewModels.firstIndex(where: { $0 === self.optionsView?.messageVM }) {
                     let indexPath = IndexPath(row: index, section: 0)
                     // 延迟是为了等cell高度刷新后再滚动
                     DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
                         if let cell = self.tableView.cellForRow(at: indexPath) {
                             // 计算cell底部加上翻译条高度
                             let cellRect = self.tableView.rectForRow(at: indexPath)
                             let translationBarHeight: CGFloat = 44 // 假设翻译条高度为44，可根据实际调整
                             let visibleRect = CGRect(x: 0, y: cellRect.maxY, width: self.tableView.bounds.width, height: translationBarHeight)
                             self.tableView.scrollRectToVisible(visibleRect, animated: true)
                         } else {
                             // cell未渲染时，直接滚动到该行
                             self.tableView.scrollToRow(at: indexPath, at: .bottom, animated: true)
                         }
                     }
                 }
                 } else {
                     YLHUD.showMessage("翻译失败")
                 }
             }
         }
    }
    
    func transResultQuery(taskId: String, from: String, to: String, optionsView: MessageOptionsView) {
        
        // 4.查询翻译结果
        YLRequest.request(OtherAPI.fileTransResult(taskId: taskId, language: from)) { result in
            switch result {
            case .success(let res):
                xLog(res.dataSources)
                guard let payload = res.dataSources?["payload"] else {
                    DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 1) {
                        self.transResultQuery(taskId: taskId, from: from, to: to, optionsView: optionsView)
                    }
                    return;
                }
                guard let sentences = payload["sentences"].arrayValue.first else {
                    xLog("翻译信息为空")
                    DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 1) {
                        self.transResultQuery(taskId: taskId, from: from, to: to, optionsView: optionsView)
                    }
                    return;
                }
                
                var text = ""
                payload["sentences"].arrayValue.forEach { jsonObj in
                    text += jsonObj["text"].stringValue
                }
                
                // 如果需要翻译，可以在这里添加翻译逻辑
                 NeoNuiTranslation.translation(from: from, to: to, text: text) { sourceText, res in
                     DispatchQueue.main.async { [weak self] in
                         YLHUD.hideHUD()
                         if let dst = res {
                             xLog("翻译结果：\(dst)")
                             optionsView.messageVM.isShowTranslation = true
                             optionsView.messageVM.translationResult = "\(text)\n(\(dst))"
                             optionsView.messageVM.setCellHeight()
                             self?.tableView.reloadData()
                         } else {
                             YLHUD.showMessage("翻译失败")
                         }
                     }
                 }
                
            case .failure(let err):
                YLHUD.showHint(.error, err.errMsg)
            }
        }
        
        
    }
    
    func uploadFile(fileURL: URL, finished: ((String) -> Void)? = nil) {
        let object = AliOSSObject.init(uploadingFileURL: fileURL, type: .file)
        AliOSSUtil.shared.uploadSingleObject(object) { bytesSent, totalBytesSent, totalBytesExpectedToSend in
            let progress = Double(totalBytesSent) / Double(totalBytesExpectedToSend)
            xLog("[上传] 上传进度 \(Int(progress*100))")
        } completion: { object, error in
            DispatchQueue.main.async {
                if error != nil {
                    YLHUD.showHint(.error, "上传失败")
                    if (finished != nil) {
                        finished?("")
                    }
                    xLog(error)
                    return
                }
                xLog(object.url)
                if (finished != nil) {
                    finished?(object.url)
                }
            }
        }
    }
    
    func replyMessage(optionsView: MessageOptionsView) {
        let fromUserName:String = optionsView.messageVM.message.info.senderUserName ?? ""
        var content:String = optionsView.messageVM.message.getShortString()
        if optionsView.messageVM.message.type == .combine {
            guard let messageVM = optionsView.messageVM as? CombineMessageViewModel else { return }
            content = messageVM.combineTitle
        }
        chatBar.replyMessage(fromUserName: fromUserName, content: content,originMessage: optionsView.messageVM.message)
    }
    
    func messageOptionsViewEmojiMessage(emoji: String, optionsView: MessageOptionsView) {
        sendEmojiCheck(emoji: emoji, messageVM: optionsView.messageVM)
        optionsView.hide()
        
    }
    
    func sendEmojiCheck(emoji: String, messageVM: MessageViewModel) {
        let containCurrentEmoji = judgeCurrentEmojiAlreadyExists(emoji: emoji, reactions: messageVM.message.reactions)
        if containCurrentEmoji == true {
            deleteMessageReaction(emoji: emoji, message: messageVM.message)
        } else {
            addMessageReaction(emoji: emoji, message: messageVM.message)
        }
    }
    
    func addMessageReaction(emoji: String,message: ZIMKitMessage ) {
        ZIMKit.addMessageReactionByMessage(for: message, reactionType: emoji) { [weak self] reaction, error in
            if error.code.rawValue != 0 {
                print("addMessageReactionByMessage errorCode: \(error.code) msg: \(error.message)")
                // HUDHelper.showErrorMessageIfNeeded(error.code.rawValue, defaultMessage: error.code.rawValue == 6000602 ? L10n("history_message_no_support_reaction") : L10n("reaction_reply_failed"))
                
            } else {
                self?.viewModel.onMessageReactionsChanged([reaction])
            }
        }
    }
    
    func deleteMessageReaction(emoji: String,message: ZIMKitMessage ) {
        ZIMKit.deleteMessageReaction(for: message, reactionType: emoji) { [weak self] reaction, error in
            print("deleteMessageReaction errorCode: \(error.code) msg: \(error.message)")
            if error.code.rawValue == 0 {
                self?.viewModel.onMessageReactionsChanged([reaction])
            }
        }
    }
    
    func deleteMessages(_ viewModels: [MessageViewModel], completion: ((Bool) -> Void)? = nil) {
        
        let popView: ZIMKitAlertView = ZIMKitAlertView.init(title: L10n("delete_message_title"), detail: L10n("message_delete_confirmation_desc_tip"), buttonCount: [L10n("conversation_cancel"),L10n("common_sure")]) {
            
        } sureBlock: { [weak self] in
            self?.deleteIMMessage(viewModels: viewModels)
            completion?(true)
        }
        popView.showView()
    }
    
    private func deleteIMMessage(viewModels:[MessageViewModel]) {
        self.tableView.performBatchUpdates { [weak self] in
            let indexPaths: [IndexPath] = viewModels.compactMap { viewModel in
                guard let row = self?.viewModel.messageViewModels.firstIndex(of: viewModel) else { return nil }
                return IndexPath(row: row, section: 0)
            }
            self?.viewModel.deleteMessages(viewModels)
            self?.tableView.beginUpdates()
            self?.tableView.deleteRows(at: indexPaths, with: .fade)
            self?.tableView.endUpdates()
        }
        // stop playing audio when delete it.
        if let playingMessageVM = self.audioPlayer.currentMessageVM {
            if viewModels.contains(playingMessageVM) {
                self.audioPlayer.stop()
            }
        }
    }
    
    func forwardMessage(messages: [MessageViewModel]) {
        // guard let unwrappedArray = messages as? [MessageViewModel]?,!unwrappedArray!.isEmpty else { return }
        if messages.count == 0 { return }
        let chatListVC = ZIMKitRecentChatListVC()
        chatListVC.forwardType = .forward
        chatListVC.conversationType = conversationType
        chatListVC.combineConversationName = messages.first!.message.getShortString()
        chatListVC.conversationList = messages.compactMap{ $0.message }
        self.navigationController?.pushViewController(chatListVC, animated: true)
    }
    
    func revokeMessage(view: MessageOptionsView) {
        
        let popView: ZIMKitAlertView = ZIMKitAlertView.init(title: L10n("revoke_message_title"), detail: L10n("revoke_message_des"), buttonCount: [L10n("conversation_cancel"),L10n("common_sure")]) {
            
        } sureBlock: { [weak self] in
            self?.viewModel.revokeMessage(view.messageVM) { error  in
                
            }
        }
        popView.showView()
    }
    
    func enableMultiSelect(_ enable: Bool, with messageVM: MessageViewModel? = nil) {
        viewModel.isShowCheckBox = enable
        for VM in viewModel.messageViewModels {
            VM.isSelected = (enable && messageVM === VM) ? true : false
        }
        chatBar.enableMultiSelect(enable)
        setupNav()
        tableView.reloadData()
    }
    
    private func judgeCurrentEmojiAlreadyExists(emoji: String,reactions: [ZIMMessageReaction]) -> Bool {
        var containEmoji = false
        for (_,reaction) in reactions.enumerated() {
            if reaction.reactionType == emoji {
                for (_,userInfo) in reaction.userList.enumerated() {
                    if userInfo.userID == ZIMKit.localUser?.id {
                        containEmoji = true
                        break
                    }
                }
            }
            if containEmoji {
                break
            }
        }
        return containEmoji
    }
}


extension ZIMKitMessagesListVC: MyIFlySpeechRecognizerDelegate {
    
    func speechRecognizerDidReceiveResult(_ result: String, isLast: Bool) {
        let sendUserId = optionsView!.messageVM.message.info.senderUserID
        var from = UserProfile.country == 0 ? "zh": "ru"
        var to = UserProfile.country == 0 ? "ru": "zh"
        
        if sendUserId != String(UserProfile.userId) {
            // 对方发的
            if let userModel = userModel {
                from = userModel.country == 0 ? "zh": "ru"
                to = userModel.country == 0 ? "ru": "zh"
            }
        }
        startTranslation(from: from, to: to, text: result)
    }
    
    func speechRecognizerDidComplete(_ error: (any Error)?) {
        
    }
    
    func speechRecognizerDidBeginRecording() {
        
    }
    
    func speechRecognizerDidEndRecording() {
        
    }
    
    func speechRecognizerDidChangeVolume(_ volume: Int) {
        
    }
    
    func speechRecognizerDidCancel() {
        
    }
    
    
    
    
}
